<?php
/**
 * ＨＴＴＰリクエストクラス
 * @author admin
 *
 */
class Lib_Request
{
	/** リクエストキー：ID */
	const KEY_ID = 'id';

	/** バリデーションエラー理由：必須チェックエラー */
	const VALUE_INVALID_REASON_REQUIRE = 'REQUIRE';
	/** バリデーションエラー理由：数字限定エラー */
	const VALUE_INVALID_REASON_NUMERIC = 'NUMERIC';
	/** バリデーションエラー理由：ＡＳＣＩＩ限定エラー */
	const VALUE_INVALID_REASON_ASCII = 'ASCII';
	/** バリデーションエラー理由：配列限定エラー */
	const VALUE_INVALID_REASON_ARRAY = 'ARRAY';
	/** バリデーションエラー理由：相関エラー */
	const VALUE_INVALID_REASON_INTERRELATED ='INTERRELATED';

	/** @var 必須リクエストリスト */
	public $ValidRequireList;
	/** @var 数字限定リクエストリスト */
	public $ValidNumericList;
	/** @var ASCII限定リクエストリスト */
	public $ValidAsciiList;
	/** @var 配列限定リクエストリスト */
	public $ValidArrayList;
	/** @var バリデーションエラー検出キー */
	public $InvalidKey='';
	/** @var バリデーションエラー理由 */
	public $InvalidReason='';

	/**
	 * コンストラクタ
	 */
	public function __construct()
	{
		$this->ValidRequireList = array();
		$this->ValidNumericList = array();
		$this->ValidAsciiList = array();
		$this->ValidArrayList = array();
	}

	/**
	 * 指定ＨＴＴＰリクエストキーの値を取得する
	 * @param  $sKey ＨＴＴＰリクエストハッシュキー
	 */
	public static function get($sKey)
	{
		$sRet = '';
		/*** 指定ＨＴＴＰリクエストキー検出 */
		if ( isset($_REQUEST[$sKey])){
			$sRet = $_REQUEST[$sKey];
		}
		return $sRet;
	}

	/**
	 * バリーデーションキークリア
	 * Enter description here ...
	 */
	public function clearValidKeyList()
	{
		$this->ValidAsciiList = array();
		$this->ValidNumericList = array();
		$this->ValidRequireList = array();
	}

	/**
	 * バリデーション
	 * Enter description here ...
	 */
	public function valid()
	{
		/*** 必須チェック */
		if ( !$this->_validRequire()) {
			return FALSE;
		}
		/*** 数字チェック */
		if ( !$this->_validNumeric()) {
			return FALSE;
		}
		/*** ASCIIチェック */
		if ( !$this->_validAscii()) {
			return FALSE;
		}
		/*** 配列チェック */
		if ( !$this->_validArray()) {
			return FALSE;
		}
		return TRUE;
	}

	/**
	 * 配列チェック
	 */
	protected function _validArray()
	{
		/*** 配列限定リクエスト走査 */
		foreach ($this->ValidArrayList as $ValidArray) {
			/*** 配列判定 */
			if ( !is_array($_REQUEST[$ValidArray])) {
				$this->InvalidKey = $ValidArray;
				$this->InvalidReason = self::VALUE_INVALID_REASON_ARRAY;
				return FALSE;
			}
		}
		return TRUE;
	}

	/**
	 * 必須チェック
	 * Enter description here ...
	 */
	protected function _validRequire()
	{
		/*** 必須ＨＴＴＰリクエスト走査 */
		foreach ($this->ValidRequireList as $ValidRequire) {
			/*** 必須チェック */
			if ( (!isset($_REQUEST[$ValidRequire])) || ($_REQUEST[$ValidRequire]=='') ) {
				$this->InvalidKey = $ValidRequire;
				$this->InvalidReason = self::VALUE_INVALID_REASON_REQUIRE;
				return FALSE;
			}
		}
		return TRUE;
	}

	/**
	 * 数字チェック
	 * Enter description here ...
	 */
	protected function _validNumeric()
	{
		/*** 数字限定ＨＴＴＰリクエスト走査  */
		foreach ($this->ValidNumericList as $ValidNumeric) {
			/*** 数字限定ＨＴＴＰリクエストキー検出 */
			if ( isset($_REQUEST[$ValidNumeric]) ) {
				/*** 数字チェック */
				if ( !is_numeric($_REQUEST[$ValidNumeric]) ) {
					$this->InvalidKey = $ValidNumeric;
					$this->InvalidReason = self::VALUE_INVALID_REASON_NUMERIC;
					return FALSE;
				}
			}
		}
		return TRUE;
	}

	/**
	 * ＡＳＣＩＩチェック
	 * Enter description here ...
	 * @return boolean
	 */
	protected function _validAscii()
	{
		/*** ASCII限定ＨＴＴＰリクエスト走査 */
		foreach ($this->ValidAsciiList as $ValidAscii) {
			/*** ＡＳＣＩＩ限定ＨＴＴＰリクエストキー検出 */
			if ( issset($_REQUEST[$ValidAscii]) ) {
				$str = $_REQUEST[$ValidAscii];
				/*** ASCII判定 */
				if(!preg_match("/^[!-~]+$/", $str)) {
					$this->InvalidKey = $ValidAscii;
					$this->InvalidReason = self::VALUE_INVALID_REASON_ASCII;
					return FALSE;
				}
			}
		}
		return TRUE;
	}

	/**
	 * ＨＴＴＰクエリー中の指定キーの値を変更する
	 * @param $aryRequest 指定キーと変更値のハッシュ
	 */
	public static function replaceQueryString($aryRequest)
	{
		$sQueryString = $_SERVER['QUERY_STRING'];
		$aryParsedUrl = parse_url($sQueryString);
		$aryParsedUrl = parse_url( $_SERVER['REQUEST_URI']);
		$aryQuery = array();
		/***
		 * ＵＲＩにクエリーがなければ何もしない
		 */
		if ( isset($aryParsedUrl['query']) ) {
			$aryDivide = explode('&', $aryParsedUrl['query']);
			/***
			 * クエリー一つ一つをハッシュ化する
			 */
			foreach ( $aryDivide as $QueryInfo ) {
				$aryDivide2 = explode('=', $QueryInfo);
				/*** イコールで２分されたらハッシュキーを設定 */
				if  ( count($aryDivide2) == 2 ) {
					$aryQuery[$aryDivide2[0]] =  $aryDivide2[1];
				}
			}
		}
		/***
		 * 置換キーを走査
		 */
		foreach ( $aryRequest as $KEY=>$VALUE ) {
			/*** 置換キーに一致するハッシュキーに置換値を設定 */
			if ( isset($aryQuery[$KEY]) ) {
				$aryQuery[$KEY] = $VALUE;
			}
		}

		$sResult = '';
		/*** スキーマ補完 */
		if ( isset($aryParsedUrl['scheme'])) {
			$sResult .= $aryParsedUrl['scheme'].'://';
		}
		/*** ホスト名補完 */
		if ( isset($aryParsedUrl['host'])){
			$sResult .= $aryParsedUrl['host'];
		}
		/*** パス補完 */
		if ( isset($aryParsedUrl['path'])){
			$sResult .= $aryParsedUrl['path'];
		}
		/*** 補完が発生したらその直後に?を補完 */
		if ( $sResult != '')
		{
			/*** 置換が発生していなければ何もしない */
			if ( count($aryQuery) > 0 ) {
				$sResult .= '?';
			}
		}

		$sQ = '';
		/***
		 * 置換ハッシュを食えリーに変換する
		 */
		foreach ( $aryQuery as $KEY=>$VALUE ) {
			/*** &補完 */
			if ( $sQ != '' ) {
				$sQ .= '&';
			}
			$sQ .= $KEY . '=' . $VALUE;
		}
		$sResult .= $sQ;
		return $sResult;
	}

	/**
	 * リクエストハッシュをクエリーに変換する
	 * @param $aryRequest リクエストハッシュ
	 */
	public static function convRequestToQuery($aryRequest = FALSE)
	{
		if ( $aryRequest === FALSE ) {
			$aryRequest = $_REQUEST;
		}

		$sResult = '';
		/**
		 * リクエストハッシュ走査
		 */
		foreach ( $aryRequest as $KEY=>$VALUE ) {
			if ( $sResult != '' ) {
				$sResult .= '&';
			}
			$sResult .= $KEY . '=' . $VALUE;
		}
		return $sResult;
	}
	
	/**
	 * クエリー文字列からキーを削除する
	 * @param unknown $sQuery
	 */
	public static function deletePramKey($sQuery, $deleteKey)
	{
		$sUrl = '';
		$divide = explode('?', $sQuery);
		/**
		 * ?が含まれていない場合は、クエリーのみが渡されたと判断する
		 */
		switch (count($divide)) {
			case 0:
				return $sQuery;
				break;
			case 1:
				break;
			case 2:
				$sUrl = $divide[0];
				$sQuery = $divide[1];
				break;
			default:
				return $sQuery;
				break;
		}
		
		$listParam = explode('&', $sQuery);
		$countParam = count($listParam);
		$i = 0;
		while ($i < $countParam) {
			$divide = explode('=', $listParam[$i]);
			if (count($divide == 2)) {
				if (trim($divide[0]) == $deleteKey) {
					unset($listParam[$i]);
				}
			}
			$i ++;
		}
		
		$sQuery = implode('&', $listParam);
		
		$sResult = '';
		if ($sUrl != '') {
			$sResult .= $sUrl . '?';
		}
		$sResult .= $sQuery;
		return $sResult;
	}
}